// 计算旋转后的坐标（传入原坐标和弧度，注意：x，y默认原点坐标为 0,0 点）
export function getReal({ x, y, rotate }) {
  let cos = Math.cos(-rotate);
  let sin = Math.sin(-rotate);
  let realX = x * cos - y * sin;
  let realY = x * sin + y * cos; // 已经将 y轴 旋转180度
  return { realX, realY };
}

// 传入点组成的数组，比较大小，返回 {minX,minY,maxX,maxY}（四个角）
export function compare(arr) {
  let map = {
    minX: arr[0][0],
    minY: arr[0][1],
    maxX: 0,
    maxY: 0,
  };
  for (let i of arr) {
    if (i[0] < map.minX) {
      map.minX = i[0];
    } else if (i[0] > map.maxX) {
      map.maxX = i[0];
    }

    if (i[1] < map.minY) {
      map.minY = i[1];
    } else if (i[1] > map.maxY) {
      map.maxY = i[1];
    }
  }
  return map;
}

// 计算圆的坐标  startX / startY: 园的中心点
export function getCircularPos({
  startX,
  startY,
  radiusX,
  radiusY,
  startAngle = 0,
  endAngle = 2 * Math.PI,
}) {
  let step = 0.1;
  let points = [];
  let positionArr = [];

  if (endAngle - startAngle < 2 * Math.PI) {
    // 判断是否是非完整球形，只考虑弧度 < 2 * Math.PI 的情况，因为此情况圆形不能闭合
    step = 0.01; // 如果非完整球形，则提升精度
    positionArr = [[startX, startY]]; // 当图案是非完整球形时，需要将开始点放入绘制的坐标中
  }

  let i = startAngle;
  while (i < endAngle) {
    points = [startX + radiusX * Math.cos(i), startY + radiusY * Math.sin(i)];
    positionArr.push(points);
    i += step;
  }
  points = [
    startX + radiusX * Math.cos(endAngle),
    startY + radiusY * Math.sin(endAngle),
  ];
  positionArr.push(points);
  return positionArr;
}

// 计算角度或弧度（传入鼠标当前点击的坐标，基于（0，0）点）
export function getAngle({ x, y }, type = "angle") {
  let rotate = Math.atan2(x, y);
  if (type === "angle") {
    return (rotate * 180) / Math.PI;
  } else if (type === "rotate") {
    return rotate;
  }
}

// 计算斜率
export function getSlope({ x, y, endX, endY }) {
  if (x === endX || y === endY) return 0;
  let slope = Number(((endY - y) / (endX - x)).toFixed(2));
  return slope;
}

// 判断是否包含某个属性
// unCondition: 需要排除的特殊属性
export function isEmpty(obj, prop, unCondition = [undefined, null]) {
  if (Object.prototype.hasOwnProperty.call(obj, prop)) {
    for (let i of unCondition) {
      if (i === null) return !isNaN(obj[prop]);
      if (unCondition.includes(obj[prop])) return false;
    }
    return true;
  }
  return false;
}

// *********** 根据直角坐标方程计算 ***********

// 计算直线方程 ax + by + c = 0
// A=y2−y1
// B=x1−x2
// C = x2 * y1 − x1 * y2
// 传入 起点xy，终点endX,endY
// 返回 {a, b, c}
export function lineEquation({ x, y, endX, endY }) {
  let a = endY - y;
  let b = x - endX;
  let c = endX * y - x * endY;
  return { a, b, c };
}

// 计算点到直线的距离
export function distanceToLine({ a, b, c }, { x, y }) {
  let distance = 0;
  let m = a * x + b * y + c;
  if (m < 0) {
    distance = -m / Math.sqrt(a * a + b * b);
    return distance;
  }
  distance = m / Math.sqrt(a * a + b * b);
  return distance;
}

// 获取曲线上某一位置的坐标
// proportion: 曲线上某一点在整个曲线中的比例，如曲线中心点为 0.5，起点为 0，终点为 1
// point1 - point4: 曲线第一个点 ~ 最后一个点的坐标
export function getThreeBezierPoint(
  proportion,
  startPoint,
  point1,
  point2,
  endPoint
) {
  const [x1, y1] = startPoint;
  const [x2, y2] = point1;
  const [x3, y3] = point2;
  const [x4, y4] = endPoint;

  const x =
    x1 * (1 - proportion) * (1 - proportion) * (1 - proportion) +
    3 * x2 * proportion * (1 - proportion) * (1 - proportion) +
    3 * x3 * proportion * proportion * (1 - proportion) +
    x4 * proportion * proportion * proportion;
  const y =
    y1 * (1 - proportion) * (1 - proportion) * (1 - proportion) +
    3 * y2 * proportion * (1 - proportion) * (1 - proportion) +
    3 * y3 * proportion * proportion * (1 - proportion) +
    y4 * proportion * proportion * proportion;
  return [x, y];
}

/**
 * 坐标转换器
 * 假设 画布宽高为 400 * 200 ， 在页面上占用的位置为 200 * 100，那么意味着：
 *    当点击页面 （50, 25） 位置的时候，实际在画布中的点击位置是  （100, 50）
 * 所以需要对鼠标点击的坐标进行换算   页面坐标 -> 画布坐标
 *
 * 作用二： 限制 点击事件的参数输入
 *  - 因为涉及到坐标转换，没有被转换的坐标最好不要随便传递
 */
export function getTransformCoordinate(canvas, { x, y, offsetX, offsetY }) {
  let computedStyle = document.defaultView.getComputedStyle(canvas);
  let positionScaleX = computedStyle.width.split("px")[0] / canvas.width;
  let positionScaleY = computedStyle.height.split("px")[0] / canvas.height;

  return {
    x: x / positionScaleX,
    y: y / positionScaleY,
    offsetX: offsetX / positionScaleX,
    offsetY: offsetY / positionScaleY,
  };
}
